home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / binutils.7 / binutils / binutils-2.7 / gas / config / atof-tahoe.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-04  |  11.1 KB  |  432 lines

  1.  
  2. /* atof_tahoe.c - turn a string into a Tahoe floating point number
  3.    Copyright (C) 1987 Free Software Foundation, Inc.
  4.    */
  5.  
  6. /* This is really a simplified version of atof_vax.c. I glommed it wholesale
  7.    and then shaved it down. I don't even know how it works. (Don't you find
  8.    my honesty refreshing?  bowen@cs.Buffalo.EDU (Devon E Bowen)
  9.  
  10.    I don't allow uppercase letters in the precision descrpitors. Ie 'f' and
  11.    'd' are allowed but 'F' and 'D' aren't */
  12.  
  13. #include "as.h"
  14.  
  15. /* Precision in LittleNums. */
  16. #define MAX_PRECISION (4)
  17. #define D_PRECISION (4)
  18. #define F_PRECISION (2)
  19.  
  20. /* Precision in chars. */
  21. #define D_PRECISION_CHARS (8)
  22. #define F_PRECISION_CHARS (4)
  23.  
  24. /* Length in LittleNums of guard bits. */
  25. #define GUARD (2)
  26.  
  27. static const long int mask[] =
  28. {
  29.   0x00000000,
  30.   0x00000001,
  31.   0x00000003,
  32.   0x00000007,
  33.   0x0000000f,
  34.   0x0000001f,
  35.   0x0000003f,
  36.   0x0000007f,
  37.   0x000000ff,
  38.   0x000001ff,
  39.   0x000003ff,
  40.   0x000007ff,
  41.   0x00000fff,
  42.   0x00001fff,
  43.   0x00003fff,
  44.   0x00007fff,
  45.   0x0000ffff,
  46.   0x0001ffff,
  47.   0x0003ffff,
  48.   0x0007ffff,
  49.   0x000fffff,
  50.   0x001fffff,
  51.   0x003fffff,
  52.   0x007fffff,
  53.   0x00ffffff,
  54.   0x01ffffff,
  55.   0x03ffffff,
  56.   0x07ffffff,
  57.   0x0fffffff,
  58.   0x1fffffff,
  59.   0x3fffffff,
  60.   0x7fffffff,
  61.   0xffffffff
  62. };
  63.  
  64.  
  65. /* Shared between flonum_gen2tahoe and next_bits */
  66. static int bits_left_in_littlenum;
  67. static LITTLENUM_TYPE *littlenum_pointer;
  68. static LITTLENUM_TYPE *littlenum_end;
  69.  
  70. #if __STDC__ == 1
  71.  
  72. int flonum_gen2tahoe (int format_letter, FLONUM_TYPE * f, LITTLENUM_TYPE * words);
  73.  
  74. #else /* not __STDC__ */
  75.  
  76. int flonum_gen2tahoe ();
  77.  
  78. #endif /* not __STDC__ */
  79.  
  80.  
  81. static int
  82. next_bits (number_of_bits)
  83.      int number_of_bits;
  84. {
  85.   int return_value;
  86.  
  87.   if (littlenum_pointer < littlenum_end)
  88.     return 0;
  89.   if (number_of_bits >= bits_left_in_littlenum)
  90.     {
  91.       return_value = mask[bits_left_in_littlenum] & *littlenum_pointer;
  92.       number_of_bits -= bits_left_in_littlenum;
  93.       return_value <<= number_of_bits;
  94.       bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits;
  95.       littlenum_pointer--;
  96.       if (littlenum_pointer >= littlenum_end)
  97.     return_value |= ((*littlenum_pointer) >> (bits_left_in_littlenum)) &
  98.       mask[number_of_bits];
  99.     }
  100.   else
  101.     {
  102.       bits_left_in_littlenum -= number_of_bits;
  103.       return_value = mask[number_of_bits] &
  104.     ((*littlenum_pointer) >> bits_left_in_littlenum);
  105.     }
  106.   return (return_value);
  107. }
  108.  
  109. static void
  110. make_invalid_floating_point_number (words)
  111.      LITTLENUM_TYPE *words;
  112. {
  113.   *words = 0x8000;        /* Floating Reserved Operand Code */
  114. }
  115.  
  116. static int            /* 0 means letter is OK. */
  117. what_kind_of_float (letter, precisionP, exponent_bitsP)
  118.      char letter;        /* In: lowercase please. What kind of float? */
  119.      int *precisionP;        /* Number of 16-bit words in the float. */
  120.      long int *exponent_bitsP;    /* Number of exponent bits. */
  121. {
  122.   int retval;            /* 0: OK. */
  123.  
  124.   retval = 0;
  125.   switch (letter)
  126.     {
  127.     case 'f':
  128.       *precisionP = F_PRECISION;
  129.       *exponent_bitsP = 8;
  130.       break;
  131.  
  132.     case 'd':
  133.       *precisionP = D_PRECISION;
  134.       *exponent_bitsP = 8;
  135.       break;
  136.  
  137.     default:
  138.       retval = 69;
  139.       break;
  140.     }
  141.   return (retval);
  142. }
  143.  
  144. /***********************************************************************\
  145. *                                    *
  146. *    Warning: this returns 16-bit LITTLENUMs, because that is    *
  147. *    what the VAX thinks in. It is up to the caller to figure    *
  148. *    out any alignment problems and to conspire for the bytes/word    *
  149. *    to be emitted in the right order. Bigendians beware!        *
  150. *                                    *
  151. \***********************************************************************/
  152.  
  153. char *                /* Return pointer past text consumed. */
  154. atof_tahoe (str, what_kind, words)
  155.      char *str;            /* Text to convert to binary. */
  156.      char what_kind;        /* 'd', 'f', 'g', 'h' */
  157.      LITTLENUM_TYPE *words;    /* Build the binary here. */
  158. {
  159.   FLONUM_TYPE f;
  160.   LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
  161.   /* Extra bits for zeroed low-order bits. */
  162.   /* The 1st MAX_PRECISION are zeroed, */
  163.   /* the last contain flonum bits. */
  164.   char *return_value;
  165.   int precision;        /* Number of 16-bit words in the format. */
  166.   long int exponent_bits;
  167.  
  168.   return_value = str;
  169.   f.low = bits + MAX_PRECISION;
  170.   f.high = NULL;
  171.   f.leader = NULL;
  172.   f.exponent = NULL;
  173.   f.sign = '\0';
  174.  
  175.   if (what_kind_of_float (what_kind, &precision, &exponent_bits))
  176.     {
  177.       return_value = NULL;    /* We lost. */
  178.       make_invalid_floating_point_number (words);
  179.     }
  180.   if (return_value)
  181.     {
  182.       memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
  183.  
  184.       /* Use more LittleNums than seems */
  185.       /* necessary: the highest flonum may have */
  186.       /* 15 leading 0 bits, so could be useless. */
  187.       f.high = f.low + precision - 1 + GUARD;
  188.  
  189.       if (atof_generic (&return_value, ".", "eE", &f))
  190.     {
  191.       make_invalid_floating_point_number (words);
  192.       return_value = NULL;    /* we lost */
  193.     }
  194.       else
  195.     {
  196.       if (flonum_gen2tahoe (what_kind, &f, words))
  197.         {
  198.           return_value = NULL;
  199.         }
  200.     }
  201.     }
  202.   return (return_value);
  203. }
  204.  
  205. /*
  206.  * In: a flonum, a Tahoe floating point format.
  207.  * Out: a Tahoe floating-point bit pattern.
  208.  */
  209.  
  210. int                /* 0: OK. */
  211. flonum_gen2tahoe (format_letter, f, words)
  212.      char format_letter;    /* One of 'd' 'f'. */
  213.      FLONUM_TYPE *f;
  214.      LITTLENUM_TYPE *words;    /* Deliver answer here. */
  215. {
  216.   LITTLENUM_TYPE *lp;
  217.   int precision;
  218.   long int exponent_bits;
  219.   int return_value;        /* 0 == OK. */
  220.  
  221.   return_value = what_kind_of_float (format_letter, &precision, &exponent_bits);
  222.   if (return_value != 0)
  223.     {
  224.       make_invalid_floating_point_number (words);
  225.     }
  226.   else
  227.     {
  228.       if (f->low > f->leader)
  229.     {
  230.       /* 0.0e0 seen. */
  231.       memset (words, '\0', sizeof (LITTLENUM_TYPE) * precision);
  232.     }
  233.       else
  234.     {
  235.       long int exponent_1;
  236.       long int exponent_2;
  237.       long int exponent_3;
  238.       long int exponent_4;
  239.       int exponent_skippage;
  240.       LITTLENUM_TYPE word1;
  241.  
  242.       /* JF: Deal with new Nan, +Inf and -Inf codes */
  243.       if (f->sign != '-' && f->sign != '+')
  244.         {
  245.           make_invalid_floating_point_number (words);
  246.           return return_value;
  247.         }
  248.       /*
  249.        * All tahoe floating_point formats have:
  250.        * Bit 15 is sign bit.
  251.        * Bits 14:n are excess-whatever exponent.
  252.        * Bits n-1:0 (if any) are most significant bits of fraction.
  253.        * Bits 15:0 of the next word are the next most significant bits.
  254.        * And so on for each other word.
  255.        *
  256.        * So we need: number of bits of exponent, number of bits of
  257.        * mantissa.
  258.        */
  259.  
  260.       bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
  261.       littlenum_pointer = f->leader;
  262.       littlenum_end = f->low;
  263.       /* Seek (and forget) 1st significant bit */
  264.       for (exponent_skippage = 0;
  265.            !next_bits (1);
  266.            exponent_skippage++)
  267.         {
  268.         }
  269.       exponent_1 = f->exponent + f->leader + 1 - f->low;
  270.       /* Radix LITTLENUM_RADIX, point just higher than f -> leader. */
  271.       exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
  272.       /* Radix 2. */
  273.       exponent_3 = exponent_2 - exponent_skippage;
  274.       /* Forget leading zeros, forget 1st bit. */
  275.       exponent_4 = exponent_3 + (1 << (exponent_bits - 1));
  276.       /* Offset exponent. */
  277.  
  278.       if (exponent_4 & ~mask[exponent_bits])
  279.         {
  280.           /*
  281.            * Exponent overflow. Lose immediately.
  282.            */
  283.  
  284.           make_invalid_floating_point_number (words);
  285.  
  286.           /*
  287.            * We leave return_value alone: admit we read the
  288.            * number, but return a floating exception
  289.            * because we can't encode the number.
  290.            */
  291.         }
  292.       else
  293.         {
  294.           lp = words;
  295.  
  296.           /* Word 1. Sign, exponent and perhaps high bits. */
  297.           /* Assume 2's complement integers. */
  298.           word1 = ((exponent_4 & mask[exponent_bits]) << (15 - exponent_bits))
  299.         | ((f->sign == '+') ? 0 : 0x8000)
  300.         | next_bits (15 - exponent_bits);
  301.           *lp++ = word1;
  302.  
  303.           /* The rest of the words are just mantissa bits. */
  304.           for (; lp < words + precision; lp++)
  305.         {
  306.           *lp = next_bits (LITTLENUM_NUMBER_OF_BITS);
  307.         }
  308.  
  309.           if (next_bits (1))
  310.         {
  311.           /*
  312.            * Since the NEXT bit is a 1, round UP the mantissa.
  313.            * The cunning design of these hidden-1 floats permits
  314.            * us to let the mantissa overflow into the exponent, and
  315.            * it 'does the right thing'. However, we lose if the
  316.            * highest-order bit of the lowest-order word flips.
  317.            * Is that clear?
  318.            */
  319.  
  320.           unsigned long int carry;
  321.  
  322.           /*
  323.             #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
  324.             Please allow at least 1 more bit in carry than is in a LITTLENUM.
  325.             We need that extra bit to hold a carry during a LITTLENUM carry
  326.             propagation. Another extra bit (kept 0) will assure us that we
  327.             don't get a sticky sign bit after shifting right, and that
  328.             permits us to propagate the carry without any masking of bits.
  329.             #endif
  330.             */
  331.           for (carry = 1, lp--;
  332.                carry && (lp >= words);
  333.                lp--)
  334.             {
  335.               carry = *lp + carry;
  336.               *lp = carry;
  337.               carry >>= LITTLENUM_NUMBER_OF_BITS;
  338.             }
  339.  
  340.           if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)))
  341.             {
  342.               make_invalid_floating_point_number (words);
  343.               /*
  344.                * We leave return_value alone: admit we read the
  345.                * number, but return a floating exception
  346.                * because we can't encode the number.
  347.                */
  348.             }
  349.         }        /* if (we needed to round up) */
  350.         }            /* if (exponent overflow) */
  351.     }            /* if (0.0e0) */
  352.     }                /* if (float_type was OK) */
  353.   return (return_value);
  354. }
  355.  
  356. /*
  357.  *        md_atof()
  358.  *
  359.  * In:    input_line_pointer -> the 1st character of a floating-point
  360.  *        number.
  361.  *    1 letter denoting the type of statement that wants a
  362.  *        binary floating point number returned.
  363.  *    Address of where to build floating point literal.
  364.  *        Assumed to be 'big enough'.
  365.  *    Address of where to return size of literal (in chars).
  366.  *
  367.  * Out:    Input_line_pointer -> of next char after floating number.
  368.  *    Error message, or 0.
  369.  *    Floating point literal.
  370.  *    Number of chars we used for the literal.
  371.  */
  372.  
  373. char *
  374. md_atof (what_statement_type, literalP, sizeP)
  375.      char what_statement_type;
  376.      char *literalP;
  377.      int *sizeP;
  378. {
  379.   LITTLENUM_TYPE words[MAX_PRECISION];
  380.   register char kind_of_float;
  381.   register int number_of_chars;
  382.   register LITTLENUM_TYPE *littlenum_pointer;
  383.  
  384.   switch (what_statement_type)
  385.     {
  386.     case 'f':            /* .ffloat */
  387.     case 'd':            /* .dfloat */
  388.       kind_of_float = what_statement_type;
  389.       break;
  390.  
  391.     default:
  392.       kind_of_float = 0;
  393.       break;
  394.     };
  395.  
  396.   if (kind_of_float)
  397.     {
  398.       register LITTLENUM_TYPE *limit;
  399.  
  400.       input_line_pointer = atof_tahoe (input_line_pointer,
  401.                        kind_of_float,
  402.                        words);
  403.       /*
  404.        * The atof_tahoe() builds up 16-bit numbers.
  405.        * Since the assembler may not be running on
  406.        * a different-endian machine, be very careful about
  407.        * converting words to chars.
  408.        */
  409.       number_of_chars = (kind_of_float == 'f' ? F_PRECISION_CHARS :
  410.              (kind_of_float == 'd' ? D_PRECISION_CHARS : 0));
  411.       know (number_of_chars <= MAX_PRECISION * sizeof (LITTLENUM_TYPE));
  412.       limit = words + (number_of_chars / sizeof (LITTLENUM_TYPE));
  413.       for (littlenum_pointer = words;
  414.        littlenum_pointer < limit;
  415.        littlenum_pointer++)
  416.     {
  417.       md_number_to_chars (literalP, *littlenum_pointer,
  418.                   sizeof (LITTLENUM_TYPE));
  419.       literalP += sizeof (LITTLENUM_TYPE);
  420.     };
  421.     }
  422.   else
  423.     {
  424.       number_of_chars = 0;
  425.     };
  426.  
  427.   *sizeP = number_of_chars;
  428.   return kind_of_float ? 0 : "Bad call to md_atof()";
  429. }
  430.  
  431. /* atof_tahoe.c */
  432.